﻿/*
 * ============ [ 废土 ] ============
 *
 * [ 维护者 ]  argoran@gmail.com
 * [  状态  ]  原型
 *
 * ============ [ 注释 ] ============
 *
 * 服务器端程序入口
 *
 * ==================================
 */

using System;
using System.Collections.Generic;
using System.IO;
using LastLand.Data.Connection;
using LastLand.Data.Global;
using LastLand.Data.World;
using Up2Link.SegString;
using Up2Link.Server;
using Up2Link.Util;

namespace LastLand.Core
{
    public class CLastLand
    {
        public static void Main(String[] _args)
        {
            CData.connections = new Dictionary<Int32, CConnection>();
            CData.userAccounts = new Dictionary<String, CUserAccount>();

            LoadData();
            
            //实例化全局变量
            CData.console = new CConsole();  //Console环境输入输出
            CData.command = new CCommand();  //服务器程序指令处理
            CData.message = new CMessage();  //服务器程序消息处理
            CData.timerEvt = new CTimerEvent();  //服务器程序计时器事件处理

            CData.serverTimerManager = new CTimerManager();  //服务器程序计时器

            //初始化游戏地图
            CData.world = new CWorld();
            CData.world.CreateNewWorld(10, 10);
            //CData.world.CreateNewWorld(2000, 4000, 1000, 2000, 1000, 1000);

            //初始化界面，测试用代码
            CData.serverOn = true;
            CData.console.SendOutput("欢迎使用", Console.ForegroundColor);
            CData.console.SendOutput("《废土 Last Land (开发代号)》", ConsoleColor.Cyan);
            CData.console.SendOutput("服务器程序");
            //CData.console.SendOutput("输入help阅读服务器使用说明");

            //启动界面线程
            CData.console.Start();

            //主线程循环
            while (CData.serverOn)
            {
                //处理服务器程序指令
                String input = CData.console.ReceiveInput();
                if (input != null)
                {
                    String[] data = input.Split(CConst.DELIMITER_COMMAND);
                    if (data.Length >= 2)
                    {
                        CData.command.ExecuteCommand(data[0].ToLowerInvariant().Trim(), data[1].ToLowerInvariant().Trim());
                    }
                    else
                    {
                        CData.command.ExecuteCommand(data[0].ToLowerInvariant().Trim(), null);
                    }
                }

                //处理服务器程序log和消息，并运行游戏系统逻辑
                if (CData.server != null && CData.server.isServerOn())
                {
                    CServerLog log = CData.server.GetServerLog();
                    if (log != null)
                    {
                        Log(CData.console, log);
                    }

                    CMessagePack<CMessageSS> msgPack = CData.server.Receive();
                    if (msgPack != null)
                    {
                        CData.message.ProcessMessage(msgPack);
                    }

                    //游戏系统逻辑
                    GameMain();
                }                

                //遇到异常时重置服务器程序
                //注意这里不会退出服务器程序主线程的循环
                if (CData.server != null && !CData.server.isServerOn())
                {
                    CData.serverTimerManager.DesactivateTimer(CData.serverTimerCombatUpdateCounter);
                    CData.serverTimerManager.DesactivateTimer(CData.serverTimerWorldUpdateCounter);
                    CData.serverTimerManager.DesactivateTimer(CData.serverTimerCharacterUpdateCounter);

                    CData.server.Close();
                    CData.server = null;
                    CData.console.SendOutput("");
                    CData.console.SendOutput("服务器遇到异常，请重新启动服务器监听");
                }
            }

            //关闭界面线程
            CData.console.Close();

            //保存用户注册信息
            SaveData();
        }

        //载入游戏数据
        //载入玩家账户信息
        private static void LoadData()
        {
            FileStream fs = new FileStream(CConst.USER_LIST_TXT, FileMode.OpenOrCreate, FileAccess.Read);
            StreamReader sr = new StreamReader(fs);

            String line = sr.ReadLine();
            while (line != null)
            {
                String[] userdata = line.Split(CConst.DELIMITER_USERACCOUNT);
                String username = userdata[0];
                String password = userdata[1];
                //Int32 index = Int32.Parse(userdata[2]);
                CData.userAccounts.Add(username, new CUserAccount(username, password, -1, null));

                line = sr.ReadLine();
            }

            sr.Close();
        }

        //存储游戏数据
        //存储玩家账户信息
        private static void SaveData()
        {
            FileStream fs = new FileStream(CConst.USER_LIST_TXT, FileMode.Create, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs);

            foreach (String username in CData.userAccounts.Keys)
            {
                String password = CData.userAccounts[username].Password;
                //Int32 index = CData.userAccounts[username].Index;
                sw.WriteLine(username + CConst.DELIMITER_USERACCOUNT + password);
            }

            sw.Close();
        }

        //处理服务器log信息
        private static void Log(CConsole _console, CServerLog _log)
        {
            if (_log.logCode == CServerLog.NEW_CLIENT_CONNECTION)
            {
                CConnection tempPlayer = new CConnection();
                CData.connections.Add(_log.logMessage, tempPlayer);

                _console.SendOutput("");
                _console.SendOutput("有一个新的用户连接到服务器");
                _console.SendOutput("服务器为他分配了" + _log.logMessage + "号连接");
            }
            else if (_log.logCode == CServerLog.CLIENT_DISCONNECTED)
            {
                //CData.connections[_log.logMessage].SaveData();
                if (CData.connections[_log.logMessage].IsLoggedIn())
                    CData.userAccounts[CData.connections[_log.logMessage].Account].ConnectionBinding = -1;
                CData.connections.Remove(_log.logMessage);

                _console.SendOutput("");
                _console.SendOutput("有一个用户从服务器掉线了");
                _console.SendOutput("他的连接号是 " + _log.logMessage);
            }
            else if (_log.logCode == CServerLog.SERVER_EXCEPTION)
            {
                _console.SendOutput("");
                _console.SendOutput("厄，我们遇到大麻烦了 ：（");
                _console.SendOutput("服务器出现未知异常");
            }
            else
            {
                _console.SendOutput("");
                _console.SendOutput("厄，我们遇到真正的大麻烦了 ：（");
                _console.SendOutput("服务器生成了不可解析的log消息");
            }
        }

        //游戏系统逻辑
        private static void GameMain()
        {
            CData.serverTimerManager.UpdateTimerPool();
            CMessageSS serverTimerEvt = CData.serverTimerManager.GetReadyTimerEvent();
            while (serverTimerEvt != null)
            {
                CData.timerEvt.ProcessTimerEvent(-1, serverTimerEvt);
                serverTimerEvt = CData.serverTimerManager.GetReadyTimerEvent();
            }

            //Int32 playerCount = CData.connections.Count;
            //for (Int32 i = 0; i < playerCount; i++)
            //{
            //    if (CData.connections[i].IsLoggedIn())
            //    {
            //        CData.connections[i].Update();

            //        CMessageSS timerEvt = CData.connections[i].GetReadyTimerEvent();
            //        while (timerEvt != null)
            //        {
            //            CData.timerEvt.ProcessTimerEvent(i, timerEvt);
            //            timerEvt = CData.connections[i].GetReadyTimerEvent();
            //        }
            //    }
            //}
        }
    }
}
